<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Tuanjie WebGL Player | {{{ PRODUCT_NAME }}}</title>
    <link rel="shortcut icon" href="TemplateData/favicon.ico">
    <link rel="stylesheet" href="TemplateData/style.css">
#if SHOW_DIAGNOSTICS
    <link rel="stylesheet" href="<<<TemplateData/diagnostics.css>>>" />
    <script src="<<<TemplateData/diagnostics.js>>>"></script>
#endif
  </head>
  <body>
    <div id="tuanjie-container" class="tuanjie-desktop">
      <canvas id="tuanjie-canvas" width=960 height=600 tabindex="-1"></canvas>
      <div id="tuanjie-loading-bar">
        <div id="tuanjie-logo"></div>
        <div id="tuanjie-progress-bar-empty">
          <div id="tuanjie-progress-bar-full"></div>
        </div>
      </div>
      <div id="tuanjie-warning"> </div>
      <div id="tuanjie-footer">
        <div id="tuanjie-webgl-logo"></div>
        <div id="tuanjie-fullscreen-button"></div>
#if SHOW_DIAGNOSTICS
        <img id="diagnostics-icon" src="TemplateData/webmemd-icon.png" />
#endif
        <div id="tuanjie-build-title">{{{ PRODUCT_NAME }}}</div>
      </div>
    </div>
	
	
    <script>
      var gameInstance;
      var container = document.querySelector("#tuanjie-container");
      var canvas = document.querySelector("#tuanjie-canvas");
      var loadingBar = document.querySelector("#tuanjie-loading-bar");
      var progressBarFull = document.querySelector("#tuanjie-progress-bar-full");
      var fullscreenButton = document.querySelector("#tuanjie-fullscreen-button");
      var warningBanner = document.querySelector("#tuanjie-warning");
#if SHOW_DIAGNOSTICS
            var diagnostics_icon = document.getElementById("diagnostics-icon");
#endif
      // Shows a temporary message banner/ribbon for a few seconds, or
      // a permanent error message on top of the canvas if type=='error'.
      // If type=='warning', a yellow highlight color is used.
      // Modify or remove this function to customize the visually presented
      // way that non-critical warnings and error messages are presented to the
      // user.
      function unityShowBanner(msg, type) {
        function updateBannerVisibility() {
          warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
        }
        var div = document.createElement('div');
        div.innerHTML = msg;
        warningBanner.appendChild(div);
        if (type == 'error') div.style = 'background: red; padding: 10px;';
        else {
          if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
          setTimeout(function() {
            warningBanner.removeChild(div);
            updateBannerVisibility();
          }, 5000);
        }
        updateBannerVisibility();
      }

      var buildUrl = "Build";
      var loaderUrl = buildUrl + "/webgl.loader.js";
      var config = {
        dataUrl: buildUrl + "/{{{ DATA_FILENAME }}}",
        frameworkUrl: buildUrl + "/{{{ FRAMEWORK_FILENAME }}}",
#if USE_THREADS
        workerUrl: buildUrl + "/{{{ WORKER_FILENAME }}}",
#endif
#if USE_WASM
        codeUrl: buildUrl + "/{{{ CODE_FILENAME }}}",
#endif
#if MEMORY_FILENAME
        memoryUrl: buildUrl + "/{{{ MEMORY_FILENAME }}}",
#endif
#if SYMBOLS_FILENAME
        symbolsUrl: buildUrl + "/{{{ SYMBOLS_FILENAME }}}",
#endif
        streamingAssetsUrl: "StreamingAssets",
        companyName: {{{ JSON.stringify(COMPANY_NAME) }}},
        productName: {{{ JSON.stringify(PRODUCT_NAME) }}},
        productVersion: {{{ JSON.stringify(PRODUCT_VERSION) }}},
        showBanner: unityShowBanner,
      };

      // By default Tuanjie keeps WebGL canvas render target size matched with
      // the DOM size of the canvas element (scaled by window.devicePixelRatio)
      // Set this to false if you want to decouple this synchronization from
      // happening inside the engine, and you would instead like to size up
      // the canvas DOM size and WebGL render target sizes yourself.
      // config.matchWebGLToCanvasSize = false;

      if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
        // Mobile device style: fill the whole browser client area with the game canvas:

        var meta = document.createElement('meta');
        meta.name = 'viewport';
        meta.content = 'width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, shrink-to-fit=yes';
        document.getElementsByTagName('head')[0].appendChild(meta);
        container.className = "tuanjie-mobile";
        canvas.className = "tuanjie-mobile";

        // To lower canvas resolution on mobile devices to gain some
        // performance, uncomment the following line:
        // config.devicePixelRatio = 1;

#if SHOW_DIAGNOSTICS
        // position the diagnostics icon in the corner on the canvas
        diagnostics_icon.style.position = "fixed";
        diagnostics_icon.style.bottom = "10px";
        diagnostics_icon.style.right = "0px";
        canvas.after(diagnostics_icon);
#endif

      } else {
        // Desktop style: Render the game canvas in a window that can be maximized to fullscreen:

              canvas.style.width = "{{{ WIDTH }}}px";
              canvas.style.height = "{{{ HEIGHT }}}px";
      }
#if BACKGROUND_FILENAME
      canvas.style.background = "url('" + buildUrl + "/{{{ BACKGROUND_FILENAME.replace(/'/g, '%27') }}}') center / cover";
#endif
      loadingBar.style.display = "block";

      var script = document.createElement("script");
      script.src = loaderUrl;
      script.onload = () => {
        createTuanjieInstance(canvas, config, (progress) => {
          progressBarFull.style.width = 100 * progress + "%";
              }).then((tuanjieInstance) => {
                loadingBar.style.display = "none";
#if SHOW_DIAGNOSTICS
                diagnostics_icon.onclick = () => {
                  tuanjieDiagnostics.openDiagnosticsDiv(tuanjieInstance.GetMemoryInfo);
                };
#endif
                fullscreenButton.onclick = () => {
                  tuanjieInstance.SetFullscreen(1);
                };
                gameInstance = tuanjieInstance;
              }).catch((message) => {
                alert(message);
              });
            };

      document.body.appendChild(script);

    </script>
    <script>
      var storage = {};
      function getStorageValue(key, defaultValue) {
        var v = storage[key];
        if (v === null) {
          return defaultValue;
        }
        if (typeof v !== 'undefined') {
          return v;
        }
        return defaultValue;
      }
      var WXWASMSDK = {
        WXInitializeSDK() {
          gameInstance.SendMessage('WXSDKManagerHandler', 'Inited', 200);
        },
        WXStorageSetIntSync(key, value) {
          storage[key] = value;
        },
        WXStorageGetIntSync(key, defaultValue) {
          return getStorageValue(key, defaultValue);
        },
        WXStorageSetFloatSync(key, value) {
          storage[key] = value;
        },
        WXStorageGetFloatSync(key, defaultValue) {
          return getStorageValue(key, defaultValue);
        },
        WXStorageSetStringSync(key, value) {
          storage[key] = value;
        },
        WXStorageGetStringSync(key, defaultValue) {
          return getStorageValue(key, defaultValue || '');
        },
        WXStorageDeleteAllSync() {
          storage = {};
        },
        WXStorageDeleteKeySync(key) {
          delete storage[key];
        },
        WXStorageHasKeySync(key) {
          return typeof storage[key] === 'undefined';
        },
        WXCheckSession(s, f, c) {},
        WXAuthorize(scope, s, f, c) {},
        WXCreateUserInfoButton(x, y, width, height, lang, withCredentials) {
          return "";
        },
        WXUserInfoButtonShow(id) {},
        WXUserInfoButtonDestroy(id) {},
        WXUserInfoButtonHide(id) {},
        WXUserInfoButtonOffTap(id) {},
        WXUserInfoButtonOnTap(id) {},
        WXOnShareAppMessage(conf, isPromise) {},
        WXOnShareAppMessageResolve(conf) {},
        WXOffShareAppMessage() {},
        WXCreateBannerAd(conf) {
          return Math.random().toString(32);
        },
        WXCreateRewardedVideoAd(conf) {
          return Math.random().toString(32);
        },
        WXCreateInterstitialAd(conf) {
          return Math.random().toString(32);
        },
        WXCreateCustomAd(conf) {},
        WXADStyleChange(id, key, value) {},
        WXShowAd(id) {},
        WXHideAd(id) {},
        WXADGetStyleValue(id, key) {},
        WXADDestroy(id) {},
        WXADLoad(id, succ, fail) {},
        WXToTempFilePathSync(conf) {},
        WXGetUserDataPath() {},
        WXWriteFileSync(filePath, data, encoding) {},
        WXCreateFixedBottomMiddleBannerAd(adUnitId, adIntervals, height) {
          return Math.random().toString(32);
        },
        WXReportGameStart() {},
        WXReportGameSceneError(sceneId, errorType, errStr, extJsonStr) {},
        WXWriteLog(str) {},
        WXWriteWarn(str) {},
        WXHideLoadingPage() {},
        WXPreloadConcurrent() {},
        WXCreateInnerAudioContext() {
          return Math.random().toString(32);
        },
        WXInnerAudioContextSetBool() {},
        WXInnerAudioContextSetString() {},
        WXInnerAudioContextSetFloat() {},
        WXInnerAudioContextGetFloat() {},
        WXInnerAudioContextGetBool() {},
        WXInnerAudioContextPlay() {},
        WXInnerAudioContextPause() {},
        WXInnerAudioContextStop() {},
        WXInnerAudioContextDestroy() {},
        WXInnerAudioContextSeek() {},
        WXInnerAudioContextAddListener(id, key) {
          if (key === 'onCanplay') {
            setTimeout(function () {
              gameInstance.SendMessage(
                'WXSDKManagerHandler',
                'OnAudioCallback',
                JSON.stringify({
                  callbackId: id,
                  errMsg: key,
                })
              );
            }, 100);
          }
        },
        WXInnerAudioContextRemoveListener() {},
        WXPreDownloadAudios(paths, id) {
          gameInstance.SendMessage(
            'WXSDKManagerHandler',
            'WXPreDownloadAudiosCallback',
            JSON.stringify({
              callbackId: id.toString(),
              errMsg: '0',
            })
          );
        },
        WXCreateVideo() {
          return Math.random().toString(32);
        },
        WXVideoPlay() {},
        WXVideoAddListener() {},
        WXVideoDestroy() {},
        WXVideoExitFullScreen() {},
        WXVideoPause() {},
        WXVideoRequestFullScreen() {},
        WXVideoSeek() {},
        WXVideoStop() {},
        WXVideoRemoveListener() {},
        WXShowOpenData() {},
        WXDownloadTexture(id, type, callback) {
          var Infos = {
            Texture: GameGlobal.TextureConfig,
            SpriteAtlas: GameGlobal.SpriteAtlasConfig,
          }[type];
          if (!Infos[id]) {
            return console.error(type + '映射id 不存在', id);
          }
          var path = Infos[id].p;
          var cid = type + '_' + id;
          if (downloadedTextures[cid]) {
            if (downloadedTextures[cid].data) {
              callback();
            } else {
              console.error(type + '映射id data 不存在！', id);
            }
          } else if (downloadingTextures[cid]) {
            downloadingTextures[cid].push(callback);
          } else {
            downloadingTextures[cid] = [callback];
            textureHandler.downloadFile(
              id,
              type,
              GameGlobal.AUDIO_PREFIX.replace(/\/$/, '') + '/' + path.replace(/\\/g, '/')
            );
          }
        },
        WXCreateGameClubButton() {
          return Math.random().toString(32);
        },
        WXGameClubButtonDestroy() {},
        WXGameClubButtonHide() {},
        WXGameClubButtonShow() {},
        WXGameClubButtonAddListener() {},
        WXGameClubButtonRemoveListener() {},
        WXGameClubButtonSetProperty() {},
        WXGameClubStyleChangeInt() {},
        WXGameClubStyleChangeStr() {},
        WXIsCloudTest() {
          return false;
        },
        WXUncaughtException() {},
        WXSetDataCDN() {},
        WXSetPreloadList() {},
        WXGetCachePath() {},
        WXGetPluginCachePath() {},
        WXGetFontRawData() {},
        WXShareFontBuffer() {},
        WXReportShareBehavior() {},
        WXShowAd2() {},
        WXToTempFilePath() {},
        WXDataContextPostMessage() {},
        WXHideOpenData() {},
        WXAccessFileSync() {},
        WXAccessFile() {},
        WXCopyFileSync() {},
        WXCopyFile() {},
        WXUnlinkSync() {},
        WXUnlink() {},
        WXReportUserBehaviorBranchAnalytics() {},
        WXCallFunction() {},
        WXCallFunctionInit() {},
        WXCloudID() {},
        WXWriteFile() {},
        WXWriteStringFile() {},
        WXAppendFile() {},
        WXAppendStringFile() {},
        WXWriteBinFileSync() {},
        WXReadFile() {},
        WXReadFileSync() {},
        WXShareFileBuffer() {},
        WXLogManagerDebug() {},
        WXLogManagerInfo() {},
        WXLogManagerLog() {},
        WXLogManagerWarn() {},
        WXCleanAllFileCache() {},
        WXCleanFileCache() {},
        WXRemoveFile() {},
        WXOnLaunchProgress() {},
        WXMkdir() {},
        WXMkdirSync() {},
        WXRmdir() {},
        WXRmdirSync() {},
        WXCameraCreateCamera() {},
        WXCameraCloseFrameChange() {},
        WXCameraDestroy() {},
        WXCameraListenFrameChange() {},
        WXCameraOnAuthCancel() {},
        WXCameraOnCameraFrame() {},
        WXCameraOnStop() {},
        WX_GetRecorderManager() {},
        WX_OnRecorderError() {},
        WX_OnRecorderFrameRecorded() {},
        WX_OnRecorderInterruptionBegin() {},
        WX_OnRecorderInterruptionEnd() {},
        WX_OnRecorderPause() {},
        WX_OnRecorderResume() {},
        WX_OnRecorderStart() {},
        WX_OnRecorderStop() {},
        WX_RecorderPause() {},
        WX_RecorderResume() {},
        WX_RecorderStart() {},
        WX_RecorderStop() {},
        WX_UploadFile() {},
        WXUploadTaskAbort() {},
        WXUploadTaskOffHeadersReceived() {},
        WXUploadTaskOffProgressUpdate() {},
        WXUploadTaskOnHeadersReceived() {},
        WXUploadTaskOnProgressUpdate() {},
        WXStat() {},
        WX_GetGameRecorder() {},
        WX_GameRecorderOff() {},
        WX_GameRecorderOn() {},
        WX_GameRecorderStart() {},
        WX_GameRecorderAbort() {},
        WX_GameRecorderPause() {},
        WX_GameRecorderResume() {},
        WX_GameRecorderStop() {},
        WX_OperateGameRecorderVideo() {},
        WXChatCreate() {},
        WXChatHide() {},
        WXChatShow() {},
        WXChatClose() {},
        WXChatOpen() {},
        WXChatSetTabs() {},
        WXChatOn() {},
        WXChatOff() {},
        WXChatSetSignature() {},
        WXSetArrayBuffer() {},
        WX_AddCard(conf, callbackId){},
        WX_AuthPrivateMessage(conf, callbackId){},
        WX_Authorize(conf, callbackId){},
        WX_CheckIsAddedToMyMiniProgram(conf, callbackId){},
        WX_CheckSession(conf, callbackId){},
        WX_ChooseImage(conf, callbackId){},
        WX_ChooseMedia(conf, callbackId){},
        WX_ChooseMessageFile(conf, callbackId){},
        WX_CloseBLEConnection(conf, callbackId){},
        WX_CloseBluetoothAdapter(conf, callbackId){},
        WX_CloseSocket(conf, callbackId){},
        WX_CreateBLEConnection(conf, callbackId){},
        WX_CreateBLEPeripheralServer(conf, callbackId){},
        WX_ExitMiniProgram(conf, callbackId){},
        WX_ExitVoIPChat(conf, callbackId){},
        WX_FaceDetect(conf, callbackId){},
        WX_GetAvailableAudioSources(conf, callbackId){},
        WX_GetBLEDeviceCharacteristics(conf, callbackId){},
        WX_GetBLEDeviceRSSI(conf, callbackId){},
        WX_GetBLEDeviceServices(conf, callbackId){},
        WX_GetBLEMTU(conf, callbackId){},
        WX_GetBatteryInfo(conf, callbackId){},
        WX_GetBeacons(conf, callbackId){},
        WX_GetBluetoothAdapterState(conf, callbackId){},
        WX_GetBluetoothDevices(conf, callbackId){},
        WX_GetChannelsLiveInfo(conf, callbackId){},
        WX_GetChannelsLiveNoticeInfo(conf, callbackId){},
        WX_GetClipboardData(conf, callbackId){},
        WX_GetConnectedBluetoothDevices(conf, callbackId){},
        WX_GetExtConfig(conf, callbackId){},
        WX_GetFuzzyLocation(conf, callbackId){},
        WX_GetGameClubData(conf, callbackId){},
        WX_GetGroupEnterInfo(conf, callbackId){},
        WX_GetInferenceEnvInfo(conf, callbackId){},
        WX_GetLocalIPAddress(conf, callbackId){},
        WX_GetLocation(conf, callbackId){},
        WX_GetNetworkType(conf, callbackId){},
        WX_GetScreenBrightness(conf, callbackId){},
        WX_GetSetting(conf, callbackId){},
        WX_GetShareInfo(conf, callbackId){},
        WX_GetStorageInfo(conf, callbackId){},
        WX_GetSystemInfo(conf, callbackId){},
        WX_GetSystemInfoAsync(conf, callbackId){},
        WX_GetUserInfo(conf, callbackId){},
        WX_GetUserInteractiveStorage(conf, callbackId){},
        WX_GetWeRunData(conf, callbackId){},
        WX_HideKeyboard(conf, callbackId){},
        WX_HideLoading(conf, callbackId){},
        WX_HideShareMenu(conf, callbackId){},
        WX_HideToast(conf, callbackId){},
        WX_InitFaceDetect(conf, callbackId){},
        WX_IsBluetoothDevicePaired(conf, callbackId){},
        WX_JoinVoIPChat(conf, callbackId){},
        WX_Login(conf, callbackId){},
        WX_MakeBluetoothPair(conf, callbackId){},
        WX_NavigateToMiniProgram(conf, callbackId){},
        WX_NotifyBLECharacteristicValueChange(conf, callbackId){},
        WX_OpenAppAuthorizeSetting(conf, callbackId){},
        WX_OpenBluetoothAdapter(conf, callbackId){},
        WX_OpenCard(conf, callbackId){},
        WX_OpenChannelsActivity(conf, callbackId){},
        WX_OpenChannelsEvent(conf, callbackId){},
        WX_OpenChannelsLive(conf, callbackId){},
        WX_OpenChannelsUserProfile(conf, callbackId){},
        WX_OpenCustomerServiceChat(conf, callbackId){},
        WX_OpenCustomerServiceConversation(conf, callbackId){},
        WX_OpenSetting(conf, callbackId){},
        WX_OpenSystemBluetoothSetting(conf, callbackId){},
        WX_PreviewImage(conf, callbackId){},
        WX_PreviewMedia(conf, callbackId){},
        WX_ReadBLECharacteristicValue(conf, callbackId){},
        WX_RemoveStorage(conf, callbackId){},
        WX_RemoveUserCloudStorage(conf, callbackId){},
        WX_ReportScene(conf, callbackId){},
        WX_RequestMidasFriendPayment(conf, callbackId){},
        WX_RequestMidasPayment(conf, callbackId){},
        WX_RequestSubscribeMessage(conf, callbackId){},
        WX_RequestSubscribeSystemMessage(conf, callbackId){},
        WX_RestartMiniProgram(conf, callbackId){},
        WX_SaveFileToDisk(conf, callbackId){},
        WX_SaveImageToPhotosAlbum(conf, callbackId){},
        WX_ScanCode(conf, callbackId){},
        WX_SendSocketMessage(conf, callbackId){},
        WX_SetBLEMTU(conf, callbackId){},
        WX_SetClipboardData(conf, callbackId){},
        WX_SetDeviceOrientation(conf, callbackId){},
        WX_SetEnableDebug(conf, callbackId){},
        WX_SetInnerAudioOption(conf, callbackId){},
        WX_SetKeepScreenOn(conf, callbackId){},
        WX_SetMenuStyle(conf, callbackId){},
        WX_SetScreenBrightness(conf, callbackId){},
        WX_SetStatusBarStyle(conf, callbackId){},
        WX_SetUserCloudStorage(conf, callbackId){},
        WX_ShowActionSheet(conf, callbackId){},
        WX_ShowKeyboard(conf, callbackId){},
        WX_ShowLoading(conf, callbackId){},
        WX_ShowModal(conf, callbackId){},
        WX_ShowShareImageMenu(conf, callbackId){},
        WX_ShowShareMenu(conf, callbackId){},
        WX_ShowToast(conf, callbackId){},
        WX_StartAccelerometer(conf, callbackId){},
        WX_StartBeaconDiscovery(conf, callbackId){},
        WX_StartBluetoothDevicesDiscovery(conf, callbackId){},
        WX_StartCompass(conf, callbackId){},
        WX_StartDeviceMotionListening(conf, callbackId){},
        WX_StartGyroscope(conf, callbackId){},
        WX_StopAccelerometer(conf, callbackId){},
        WX_StopBeaconDiscovery(conf, callbackId){},
        WX_StopBluetoothDevicesDiscovery(conf, callbackId){},
        WX_StopCompass(conf, callbackId){},
        WX_StopDeviceMotionListening(conf, callbackId){},
        WX_StopFaceDetect(conf, callbackId){},
        WX_StopGyroscope(conf, callbackId){},
        WX_UpdateKeyboard(conf, callbackId){},
        WX_UpdateShareMenu(conf, callbackId){},
        WX_UpdateVoIPChatMuteConfig(conf, callbackId){},
        WX_UpdateWeChatApp(conf, callbackId){},
        WX_VibrateLong(conf, callbackId){},
        WX_VibrateShort(conf, callbackId){},
        WX_WriteBLECharacteristicValue(conf, callbackId){},
        WX_StartGameLive(conf, callbackId){},
        WX_CheckGameLiveEnabled(conf, callbackId){},
        WX_GetUserCurrentGameliveInfo(conf, callbackId){},
        WX_GetUserRecentGameLiveInfo(conf, callbackId){},
        WX_GetUserGameLiveDetails(conf, callbackId){},
        WX_OpenChannelsLiveCollection(conf, callbackId){},
        WX_OpenPage(conf, callbackId){},
        WX_RequestMidasPaymentGameItem(conf, callbackId){},

        WX_OperateGameRecorderVideo() {},
        WX_RemoveStorageSync() {},
        WX_ReportEvent() {},
        WX_ReportMonitor() {},
        WX_ReportPerformance() {},
        WX_ReportUserBehaviorBranchAnalytics() {},
        WX_ReserveChannelsLive() {},
        WX_RevokeBufferURL() {},
        WX_SetPreferredFramesPerSecond() {},
        WX_SetStorageSync() {},
        WX_ShareAppMessage() {},
        WX_TriggerGC() {},

        WX_OnAccelerometerChange() {},
        WX_OffAccelerometerChange() {},
        WX_OnAudioInterruptionBegin() {},
        WX_OffAudioInterruptionBegin() {},
        WX_OnAudioInterruptionEnd() {},
        WX_OffAudioInterruptionEnd() {},
        WX_OnBLECharacteristicValueChange() {},
        WX_OffBLECharacteristicValueChange() {},
        WX_OnBLEConnectionStateChange() {},
        WX_OffBLEConnectionStateChange() {},
        WX_OnBLEMTUChange() {},
        WX_OffBLEMTUChange() {},
        WX_OnBLEPeripheralConnectionStateChanged() {},
        WX_OffBLEPeripheralConnectionStateChanged() {},
        WX_OnBeaconServiceChange() {},
        WX_OffBeaconServiceChange() {},
        WX_OnBeaconUpdate() {},
        WX_OffBeaconUpdate() {},
        WX_OnBluetoothAdapterStateChange() {},
        WX_OffBluetoothAdapterStateChange() {},
        WX_OnBluetoothDeviceFound() {},
        WX_OffBluetoothDeviceFound() {},
        WX_OnCompassChange() {},
        WX_OffCompassChange() {},
        WX_OnDeviceMotionChange() {},
        WX_OffDeviceMotionChange() {},
        WX_OnDeviceOrientationChange() {},
        WX_OffDeviceOrientationChange() {},
        WX_OnError() {},
        WX_OffError() {},
        WX_OnGyroscopeChange() {},
        WX_OffGyroscopeChange() {},
        WX_OnHide() {},
        WX_OffHide() {},
        WX_OnInteractiveStorageModified() {},
        WX_OffInteractiveStorageModified() {},
        WX_OnKeyDown() {},
        WX_OffKeyDown() {},
        WX_OnKeyUp() {},
        WX_OffKeyUp() {},
        WX_OnKeyboardComplete() {},
        WX_OffKeyboardComplete() {},
        WX_OnKeyboardConfirm() {},
        WX_OffKeyboardConfirm() {},
        WX_OnKeyboardHeightChange() {},
        WX_OffKeyboardHeightChange() {},
        WX_OnKeyboardInput() {},
        WX_OffKeyboardInput() {},
        WX_OnMemoryWarning() {},
        WX_OffMemoryWarning() {},
        WX_OnMessage() {},
        WX_OnNetworkStatusChange() {},
        WX_OffNetworkStatusChange() {},
        WX_OnNetworkWeakChange() {},
        WX_OffNetworkWeakChange() {},
        WX_OnShareMessageToFriend() {},
        WX_OnShow() {},
        WX_OffShow() {},
        WX_OnSocketClose() {},
        WX_OnSocketError() {},
        WX_OnSocketMessage() {},
        WX_OnSocketOpen() {},
        WX_OnTouchCancel() {},
        WX_OffTouchCancel() {},
        WX_OnTouchEnd() {},
        WX_OffTouchEnd() {},
        WX_OnTouchMove() {},
        WX_OffTouchMove() {},
        WX_OnTouchStart() {},
        WX_OffTouchStart() {},
        WX_OnUnhandledRejection() {},
        WX_OffUnhandledRejection() {},
        WX_OnUserCaptureScreen() {},
        WX_OffUserCaptureScreen() {},
        WX_OnVoIPChatInterrupted() {},
        WX_OffVoIPChatInterrupted() {},
        WX_OnVoIPChatMembersChanged() {},
        WX_OffVoIPChatMembersChanged() {},
        WX_OnVoIPChatSpeakersChanged() {},
        WX_OffVoIPChatSpeakersChanged() {},
        WX_OnVoIPChatStateChanged() {},
        WX_OffVoIPChatStateChanged() {},
        WX_OnWheel() {},
        WX_OffWheel() {},
        WX_OnWindowResize() {},
        WX_OffWindowResize() {},

        WX_OnAddToFavorites() {},
        WX_OnAddToFavorites_Resolve(conf){},
        WX_OffAddToFavorites() {},
        WX_OnCopyUrl() {},
        WX_OnCopyUrl_Resolve(conf){},
        WX_OffCopyUrl() {},
        WX_OnHandoff() {},
        WX_OnHandoff_Resolve(conf){},
        WX_OffHandoff() {},
        WX_OnShareTimeline() {},
        WX_OnShareTimeline_Resolve(conf){},
        WX_OffShareTimeline() {},
        WX_OnGameLiveStateChange() {},
        WX_OnGameLiveStateChange_Resolve(conf){},
        WX_OffGameLiveStateChange() {},

        WX_SetHandoffQuery(query){
            return "";
        },
        WX_GetAccountInfoSync(){
            return JSON.stringify({});
        },
        WX_GetAppAuthorizeSetting(){
            return JSON.stringify({});
        },
        WX_GetAppBaseInfo(){
            return JSON.stringify({});
        },
        WX_GetBatteryInfoSync(){
            return JSON.stringify({});
        },
        WX_GetDeviceInfo(){
            return JSON.stringify({});
        },
        WX_GetEnterOptionsSync(){
            return JSON.stringify({});
        },
        WX_GetExptInfoSync(keys){
            return JSON.stringify({});
        },
        WX_GetExtConfigSync(){
            return JSON.stringify({});
        },
        WX_GetLaunchOptionsSync(){
            return JSON.stringify({});
        },
        WX_GetMenuButtonBoundingClientRect(){
            return JSON.stringify({});
        },
        WX_GetStorageInfoSync(){
            return JSON.stringify({});
        },
        WX_GetSystemInfoSync(){
            return JSON.stringify({});
        },
        WX_GetSystemSetting(){
            return JSON.stringify({});
        },
        WX_GetWindowInfo(){
            return JSON.stringify({});
        },
        WX_CreateImageData(){
            return JSON.stringify({});
        },
        WX_CreatePath2D(){
            return JSON.stringify({});
        },
        WX_SetCursor(path, x, y){
            return "";
        },
        WX_SetMessageToFriendQuery(option){
            return "";
        },
        WX_GetTextLineHeight(option){
            return "";
        },
        WX_LoadFont(path){
            return "";
        },
        WX_GetGameLiveState(){
            return JSON.stringify({});
        },

        WX_CreateFeedbackButton() {return ""},
        WX_GetLogManager() {return ""},
        WX_GetRealtimeLogManager() {return ""},
        WX_GetUpdateManager() {return ""},
        WX_CreateVideoDecoder() {return ""},

        WXFeedbackButtonSetProperty() {},
        WX_FeedbackButtonDestroy() {},
        WX_FeedbackButtonHide() {},
        WX_FeedbackButtonOffTap() {},
        WX_FeedbackButtonOnTap() {},
        WX_FeedbackButtonShow() {},
        WX_LogManagerDebug() {},
        WX_LogManagerInfo() {},
        WX_LogManagerLog() {},
        WX_LogManagerWarn() {},
        WX_RealtimeLogManagerAddFilterMsg() {},
        WX_RealtimeLogManagerError() {},
        WX_RealtimeLogManagerInfo() {},
        WX_RealtimeLogManagerSetFilterMsg() {},
        WX_RealtimeLogManagerWarn() {},
        WX_UpdateManagerApplyUpdate() {},
        WX_UpdateManagerOnCheckForUpdate() {},
        WX_UpdateManagerOnUpdateFailed() {},
        WX_UpdateManagerOnUpdateReady() {},
        WX_VideoDecoderGetFrameData() {},
        WX_VideoDecoderRemove() {},
        WX_VideoDecoderSeek() {},
        WX_VideoDecoderStart() {},
        WX_VideoDecoderStop() {},
        WX_VideoDecoderOff() {},
        WX_VideoDecoderOn() {},
      };
      var downloadedTextures = {};
      var downloadingTextures = {};
      var textureHandler = {
        downloadFile(textureId, type, prefix) {
          var url = prefix + '.png';
          var cid = type + '_' + textureId;
          var image = new Image();
          image.src = url;
          image.onload = function () {
            downloadedTextures[cid] = {
              data: image,
            };
            if (downloadingTextures[cid] instanceof Array) {
              downloadingTextures[cid].forEach(v => v());
            } else {
              downloadingTextures[cid]();
            }
            delete downloadingTextures[cid];
          };
          image.onerror = function () {
            console.error(url + ' 下载失败！');
          };
        },
      };

      var GameGlobal = {
        TextureConfig: {},
        SpriteAtlasConfig: {},
        DownloadedTextures: downloadedTextures,
        AUDIO_PREFIX: './Assets/Textures/',
      };
      window._ScaleRate = 1;
    </script>
  </body>
</html>
